#include "RanGen.h"

#include <time.h>

RanGen::RanGen(void)
{
	rseed = 666;
	mti = RAND_N+1;
}

int	RanGen::Random(int min, int max)
{
	unsigned int n = max-min;
	unsigned long y;

	static unsigned long mag01[2] = { 0x0, RAND_MATRIX_A };

	if( n == 0 )
		return 0;

	if( mti >= RAND_N )
	{
		int kk = 0;

		if( mti == RAND_N+1 )
			SeedRandom(7331);

		for(kk=0; kk < RAND_N-RAND_M; kk++)
		{
			y = (mt[kk]&RAND_UPPER_MASK) | (mt[kk+1]&RAND_LOWER_MASK);
			mt[kk] = mt[kk+RAND_M] ^ (y >> 11) ^ mag01[y & 0x1];
		}

		for(; kk < RAND_N-1; kk++)
		{
			y = (mt[kk]&RAND_UPPER_MASK) | (mt[kk+1]&RAND_LOWER_MASK);
			mt[kk] = mt[kk+(RAND_M-RAND_N)] ^ (y >> 11) ^ mag01[y & 0x1];
		}

		y = (mt[RAND_N-1]&RAND_UPPER_MASK) | (mt[0]&RAND_LOWER_MASK);
		mt[RAND_N-1] = mt[RAND_M-1] ^ (y >> 11) ^ mag01[y & 0x1];

		mti = 0;
	}
	
	y = mt[mti++];
	y ^= RAND_TEMPERING_SHIFT_U(y);
	y ^= RAND_TEMPERING_SHIFT_S(y) & RAND_TEMPERING_MASK_B;
	y ^= RAND_TEMPERING_SHIFT_T(y) & RAND_TEMPERING_MASK_C;
	y ^= RAND_TEMPERING_SHIFT_L(y);

	return (y%n)+min;
}

void RanGen::SeedRandom(unsigned int n)
{
	mt[0] = n & 0xffffffff;
	for(mti = 1; mti < RAND_N; mti++)
		mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;

	rseed = n;
}

unsigned int RanGen::GetRandomSeed(void)
{
	return(rseed);
}

void RanGen::SeedRandom(void)
{
	SeedRandom((unsigned int)time(NULL));
}